package cn.zhaopin.starter.security.handler;

import cn.zhaopin.starter.security.basic.CodeException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

/**
 * Description: 认证失败处理
 *
 * @author zuomin (myleszelic@outlook.com)
 * @date: 2021/09/30-09:26
 */
public class BasicAuthenticationFailureHandler implements ServerAuthenticationFailureHandler {

    @SuppressWarnings("BlockingMethodInNonBlockingContext")
    @Override
    public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) {
        CodeException codeException = (CodeException) exception;
        ServerHttpResponse response = webFilterExchange.getExchange().getResponse();

        HttpHeaders headers = response.getHeaders();
        headers.set("Content-Type", MediaType.APPLICATION_JSON_VALUE);
        headers.set("Cache-Control", "no-store,no-cache,must-revalidate,max-age-8");
        byte[] dataBytes = {};
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> resMap  = new HashMap<>();
        try {
            resMap.put("code", codeException.getCode());
            resMap.put("message", codeException.getMsg());
            resMap.put("httpCode", HttpStatus.UNAUTHORIZED.value());
            dataBytes = mapper.writeValueAsBytes(resMap);
        } catch (JsonProcessingException jsonProcessingException) {
            jsonProcessingException.printStackTrace();
        }

        DataBuffer bodyDateBuffer = response.bufferFactory().wrap(dataBytes);
        return response.writeWith(Mono.just(bodyDateBuffer));
    }
}
